package com.zhs.study.aop;

import com.zhs.study.util.RedisUtil;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;


/**
 * @author zhenghuisheng
 * @date : 2023/5/22
 */
@Aspect
@Component
@Slf4j
public class CmdMethodAdvice {

    @Resource
    private RedisUtil redisUtil;

    /**
     * 前置通知开启定时任务
     *
     * @throws Exception
     */
    @Before(value = "execution(* com.zhs.study.controller.UserController.getById(..))")
    public void doBeforeTimeTest(JoinPoint joinPoint){
        log.info("==========前置通知，开始执行" + System.currentTimeMillis());
        Object[] args = joinPoint.getArgs(); // 参数值
        String[] argNames = ((MethodSignature)joinPoint.getSignature()).getParameterNames(); // 参数名
        System.out.println(args[0]);
        System.out.println(argNames);
    }

    /**
     * 后置通知，方法结束之后
     *
     * @throws Exception
     */
    @After(value = "execution(public * com.zhs.study.controller.UserController.getById(..))")
    public void doAfterTimeTest(JoinPoint joinPoint) {
        log.info("==========后置通知，开始执行" + System.currentTimeMillis());
        String methodName = joinPoint.getSignature().getName();
        log.info("后置通知，方法名称为：" + methodName);
    }

    //定义在controller包和所有子包里的任意类的public方法的执行
    @Pointcut("execution(public * com.zhs.study.controller.UserController.getById(..))")
    public void getById(){

    }

    //切入点的增强器
    @Around("getById()")
    public Object timeAround(ProceedingJoinPoint joinPoint) throws Throwable {
        Object obj;
        // 获取开始时间
        long startTime = System.currentTimeMillis();
        // 获取返回结果集
        obj = joinPoint.proceed(joinPoint.getArgs());
        // 获取方法执行时间
        long endTime= System.currentTimeMillis() - startTime;
        String classAndMethod = joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName();
        log.info("执行 " + classAndMethod + " 耗时为：" + endTime+ "ms");
        return obj;
    }
}
